package errors

import (
	"fmt"
	"net/http"
)

// ErrorCode 错误码类型
type ErrorCode int

// 定义错误码常量
const (
	// 通用错误码 (1000-1999)
	Success           ErrorCode = 1000 // 成功
	InternalError     ErrorCode = 1001 // 内部错误
	InvalidParams     ErrorCode = 1002 // 参数错误
	Unauthorized      ErrorCode = 1003 // 未授权
	Forbidden         ErrorCode = 1004 // 禁止访问
	NotFound          ErrorCode = 1005 // 资源不存在
	Conflict          ErrorCode = 1006 // 资源冲突
	TooManyRequests   ErrorCode = 1007 // 请求过多
	ValidationFailed  ErrorCode = 1008 // 验证失败

	// 用户相关错误码 (2000-2999)
	UserNotFound      ErrorCode = 2001 // 用户不存在
	UserExists        ErrorCode = 2002 // 用户已存在
	InvalidPassword   ErrorCode = 2003 // 密码错误
	PasswordTooWeak   ErrorCode = 2004 // 密码强度不够
	UserDisabled      ErrorCode = 2005 // 用户已禁用
	TokenExpired      ErrorCode = 2006 // Token已过期
	TokenInvalid      ErrorCode = 2007 // Token无效
	InvalidUsername   ErrorCode = 2008 // 用户名格式错误
	EmailExists       ErrorCode = 2009 // 邮箱已存在

	// 帖子相关错误码 (3000-3999)
	PostNotFound      ErrorCode = 3001 // 帖子不存在
	PostExists        ErrorCode = 3002 // 帖子已存在
	PostDeleted       ErrorCode = 3003 // 帖子已删除
	PostNotOwner      ErrorCode = 3004 // 非帖子作者
	PostLikeExists    ErrorCode = 3005 // 已点赞
	PostLikeNotExists ErrorCode = 3006 // 未点赞
	PostFavExists     ErrorCode = 3007 // 已收藏
	PostFavNotExists  ErrorCode = 3008 // 未收藏

	// 分类相关错误码 (4000-4999)
	CategoryNotFound  ErrorCode = 4001 // 分类不存在
	CategoryExists    ErrorCode = 4002 // 分类已存在
	CategoryHasPosts  ErrorCode = 4003 // 分类下有帖子

	// 评论相关错误码 (5000-5999)
	CommentNotFound   ErrorCode = 5001 // 评论不存在
	CommentDeleted    ErrorCode = 5002 // 评论已删除
	CommentNotOwner   ErrorCode = 5003 // 非评论作者
	ParentNotFound    ErrorCode = 5004 // 父评论不存在

	// AI相关错误码 (6000-6999)
	AIServiceError    ErrorCode = 6001 // AI服务错误
	AIQuotaExceeded   ErrorCode = 6002 // AI配额超限
	AIModelNotFound   ErrorCode = 6003 // AI模型不存在
)

// AppError 应用错误结构
type AppError struct {
	Code    ErrorCode `json:"code"`
	Message string    `json:"message"`
	Detail  string    `json:"detail,omitempty"`
}

// Error 实现error接口
func (e *AppError) Error() string {
	if e.Detail != "" {
		return fmt.Sprintf("[%d] %s: %s", e.Code, e.Message, e.Detail)
	}
	return fmt.Sprintf("[%d] %s", e.Code, e.Message)
}

// New 创建新的应用错误
func New(code ErrorCode, message string, detail ...string) *AppError {
	err := &AppError{
		Code:    code,
		Message: message,
	}
	if len(detail) > 0 {
		err.Detail = detail[0]
	}
	return err
}

// 错误码到HTTP状态码的映射
var codeToHTTPStatus = map[ErrorCode]int{
	Success:           http.StatusOK,
	InternalError:     http.StatusInternalServerError,
	InvalidParams:     http.StatusBadRequest,
	Unauthorized:      http.StatusUnauthorized,
	Forbidden:         http.StatusForbidden,
	NotFound:          http.StatusNotFound,
	Conflict:          http.StatusConflict,
	TooManyRequests:   http.StatusTooManyRequests,
	ValidationFailed:  http.StatusBadRequest,
	UserNotFound:      http.StatusNotFound,
	UserExists:        http.StatusConflict,
	InvalidPassword:   http.StatusUnauthorized,
	PasswordTooWeak:   http.StatusBadRequest,
	UserDisabled:      http.StatusForbidden,
	TokenExpired:      http.StatusUnauthorized,
	TokenInvalid:      http.StatusUnauthorized,
	InvalidUsername:   http.StatusBadRequest,
	EmailExists:       http.StatusConflict,
	PostNotFound:      http.StatusNotFound,
	PostExists:        http.StatusConflict,
	PostDeleted:       http.StatusGone,
	PostNotOwner:      http.StatusForbidden,
	PostLikeExists:    http.StatusConflict,
	PostLikeNotExists: http.StatusNotFound,
	PostFavExists:     http.StatusConflict,
	PostFavNotExists:  http.StatusNotFound,
	CategoryNotFound:  http.StatusNotFound,
	CategoryExists:    http.StatusConflict,
	CategoryHasPosts:  http.StatusConflict,
	CommentNotFound:   http.StatusNotFound,
	CommentDeleted:    http.StatusGone,
	CommentNotOwner:   http.StatusForbidden,
	ParentNotFound:    http.StatusNotFound,
	AIServiceError:    http.StatusServiceUnavailable,
	AIQuotaExceeded:   http.StatusTooManyRequests,
	AIModelNotFound:   http.StatusNotFound,
}

// GetHTTPStatus 获取错误码对应的HTTP状态码
func (e *AppError) GetHTTPStatus() int {
	if status, ok := codeToHTTPStatus[e.Code]; ok {
		return status
	}
	return http.StatusInternalServerError
}

// 预定义的错误实例
var (
	// 通用错误
	ErrInternalError     = New(InternalError, "内部服务器错误")
	ErrInvalidParams     = New(InvalidParams, "参数错误")
	ErrUnauthorized      = New(Unauthorized, "未授权")
	ErrForbidden         = New(Forbidden, "禁止访问")
	ErrNotFound          = New(NotFound, "资源不存在")
	ErrConflict          = New(Conflict, "资源冲突")
	ErrValidationFailed  = New(ValidationFailed, "验证失败")
	
	// 用户相关错误
	ErrUserNotFound      = New(UserNotFound, "用户不存在")
	ErrInvalidUsername   = New(InvalidUsername, "用户名格式错误")
	ErrUserExists        = New(UserExists, "用户名已存在")
	ErrEmailExists       = New(EmailExists, "邮箱已存在")
	ErrInvalidCredentials = New(InvalidPassword, "用户名或密码错误")
	ErrInvalidPassword   = New(InvalidPassword, "用户名或密码错误")
	ErrWeakPassword      = New(PasswordTooWeak, "密码强度不够")
	ErrPasswordTooWeak   = New(PasswordTooWeak, "密码强度不够")
	ErrUserDisabled      = New(UserDisabled, "用户已被禁用")
	ErrTokenExpired      = New(TokenExpired, "Token已过期")
	ErrTokenInvalid      = New(TokenInvalid, "Token无效")
	ErrInvalidToken      = New(TokenInvalid, "无效的Token")
	
	// 帖子相关错误
	ErrPostNotFound      = New(PostNotFound, "帖子不存在")
	ErrPostExists        = New(PostExists, "帖子已存在")
	ErrPostDeleted       = New(PostDeleted, "帖子已删除")
	ErrPostNotOwner      = New(PostNotOwner, "只有作者可以操作")
	ErrPostLikeExists    = New(PostLikeExists, "已经点赞过了")
	ErrPostLikeNotExists = New(PostLikeNotExists, "还未点赞")
	ErrPostFavExists     = New(PostFavExists, "已经收藏过了")
	ErrPostFavNotExists  = New(PostFavNotExists, "还未收藏")
	
	// 分类相关错误
	ErrCategoryNotFound  = New(CategoryNotFound, "分类不存在")
	ErrCategoryExists    = New(CategoryExists, "分类名已存在")
	ErrCategoryHasPosts  = New(CategoryHasPosts, "分类下还有帖子，无法删除")
	
	// 评论相关错误
	ErrCommentNotFound   = New(CommentNotFound, "评论不存在")
	ErrCommentDeleted    = New(CommentDeleted, "评论已删除")
	ErrCommentNotOwner   = New(CommentNotOwner, "只有作者可以操作")
	ErrParentNotFound    = New(ParentNotFound, "父评论不存在")
	
	// AI相关错误
	ErrAIServiceError    = New(AIServiceError, "AI服务暂时不可用")
	ErrAIQuotaExceeded   = New(AIQuotaExceeded, "AI服务配额已用完")
	ErrAIModelNotFound   = New(AIModelNotFound, "AI模型不存在")
)

// IsAppError 判断是否为应用错误
func IsAppError(err error) (*AppError, bool) {
	if appErr, ok := err.(*AppError); ok {
		return appErr, true
	}
	return nil, false
}

// WrapError 包装标准错误为应用错误
func WrapError(err error, code ErrorCode, message string) *AppError {
	if err == nil {
		return nil
	}
	return New(code, message, err.Error())
}